<template>
  <section class="multi-workbook">
    <section class="multi-workbook-left">
      <section class="multi-workbook-left-top el-card">
        <section style="width: 100%;height:100%;position: absolute;transition: top .5s"
                 :style="{ top : currentWorkBookIndex * (-100) + '%' }">
          <gc-spread-sheets style="height: 100%" v-for="(item,index) in workBookList" :key="item.id"
                            @workbookInitialized="e=> initSpread(e,index)">
          </gc-spread-sheets>
        </section>
      </section>
      <el-scrollbar class="multi-workbook-bottom">
        <section style="display: flex">
          <el-button v-for="(item,index) in workBookList" :key="item.id"
                     :type="currentWorkBookIndex == index ? 'primary':'default'"
                     @click="currentWorkBookIndex = index">
            {{ item.name }}
          </el-button>
        </section>
      </el-scrollbar>
    </section>
    <section class="multi-workbook-right">
      <el-upload :show-file-list="false" v-model:file-list="fileList" :auto-upload="false" :accept="['.xlsx','.xlx']"
                 :on-change="handleFileChange">
        <el-button :icon="Files">缓存文件（点击上传）</el-button>
      </el-upload>
      <el-input v-show="formulaEditing"></el-input>
    </section>
  </section>
</template>

<script setup lang="ts">
//多工作簿
import {ref, toRaw} from "vue";
import "@grapecity-software/spread-sheets-vue";
import GC from "@grapecity-software/spread-sheets";
import "@grapecity-software/spread-sheets-io";
import '@grapecity-software/spread-sheets-resources-zh';
import {Files} from "@element-plus/icons-vue";
import type {UploadFile, UploadUserFile} from "element-plus";
import {
  type FileType,
  getFileType,
  openOptions,
  openOptionsConfig,
  saveOptions,
  saveOptionsConfig
} from "../views/constant.ts";

GC.Spread.Common.CultureManager.culture("zh-cn");

interface WorkBookItem {
  id: string;
  name: string;
  spread: GC.Spread.Sheets.Workbook | null;
  file: File | null
}

let workBookList = ref<WorkBookItem[]>([])
let fileList = ref<UploadUserFile[]>([]);
let currentWorkBookIndex = ref(0);
let formulaEditing = ref(false);// 是否在表格公式编辑状态
let formulaEditingCell = ref({
  spreadIndex: -1,
  sheetName: '',
  row: -1,
  col: -1,
  text:'',
})

// 判断是否是属于编辑中:字符串=“=”时；或者以加减乘除结尾
function validIsFormulaEditing(str: string) {
  return str === '=' || str.endsWith('+') || str.endsWith('-') || str.endsWith('*') || str.endsWith('/');
}

function initSpread(spread: GC.Spread.Sheets.Workbook, index: number) {
  currentWorkBookIndex.value = index;
  let options = getOptions('open');
  const file = workBookList.value[index].file
  if (!spread || !file) return;
  spread.import(file, function () {
    // spread.removeSheet(0) // 删除默认的 授权说明sheet
    spread.bind(GC.Spread.Sheets.Events.EditChange, (sender: any, args: any) => {
      console.log('CellChanged', args)
      if (validIsFormulaEditing(args.editingText)) {
        formulaEditing.value = true
        formulaEditingCell.value.text = args.editingText
        formulaEditingCell.value.spreadIndex = index
        formulaEditingCell.value.sheetName = args.sheetName
        formulaEditingCell.value.row = args.row
        formulaEditingCell.value.col = args.col
      }
    })
    spread.bind(GC.Spread.Sheets.Events.SelectionChanged, (sender: any, args: any) => {
      console.log('SelectionChanged', args)
      if (!formulaEditing.value) return
      const sheet = spread.getActiveSheet();
      let temp = args.newSelections[0]
      const data = sheet?.getArray(temp.row, temp.col, temp.rowCount, temp.colCount)
      // data是一个二维数组，计算出数组的和，并设置到单元格中
      if (data) {
        let sum = 0;
        for (let i = 0; i < data.length; i++) {
          for (let j = 0; j < data[i].length; j++) {
            sum += data[i][j];
          }
        }
        console.log(sum)
      }
      renderFormula(index, args.sheetName, temp)
    })
  }, function () {
  }, options);
  workBookList.value[index].spread = spread;
}

// TODO 索引转A1
// 同一个工作簿不需要处理
function renderFormula(spreadIndex: number, sheetName: string, range: GC.Spread.Sheets.Range) {
  if (spreadIndex == formulaEditingCell.value.spreadIndex) return;
  // 构造单元格公式
  let formula = '';
  let rangeStr = GC.Spread.Sheets.CalcEngine.rangeToFormula(range)
  console.log(rangeStr)
  // 删除字符串中的$
  rangeStr = rangeStr.replace(/\$/g, '')
  formula = formulaEditingCell.value.text + `[${workBookList.value[spreadIndex].name}]${sheetName}!${rangeStr}`
  console.log(formula)
  const spread = toRaw(workBookList.value[formulaEditingCell.value.spreadIndex].spread)
  const targetSpread = toRaw(workBookList.value[spreadIndex].spread)
  spread?.suspendPaint();
  const sheet = spread?.getSheetFromName(formulaEditingCell.value.sheetName)
  console.log(sheet?.getCell(1,1),formulaEditingCell.value)
  sheet?.setFormula(formulaEditingCell.value.row, formulaEditingCell.value.col, formula)
  spread?.getExternalReferences().forEach((item: any) => {
    console.log(item)
    spread?.updateExternalReference(item.name,targetSpread?.toJSON())
  })
  spread?.resumePaint();
}


const openFileType = ref<FileType>('xlsx');
const saveFileType = ref<FileType>('xlsx');
const getOptions = function (mode: string) {
  let optionsConfig, optionsValue;
  if (mode === 'open') {
    optionsConfig = openOptionsConfig[openFileType.value];
    optionsValue = openOptions;
  } else {
    optionsConfig = saveOptionsConfig[saveFileType.value];
    optionsValue = saveOptions;
  }

  let options: any = {};
  optionsConfig.forEach((prop: any) => {
    // @ts-ignore
    let v = optionsValue[prop.propName];
    if (prop.type === 'number') {
      v = +v;
    }
    options[prop.propName] = v;
  });

  return options;
}

function handleFileChange(uploadFile: UploadFile) {
  const file = uploadFile.raw as File;

  workBookList.value.push({
    id: Date.now().toString(),
    name: file.name,
    spread: null,
    file: file
  })

}
</script>

<style scoped lang="less">
.multi-workbook {
  width: 1800px;
  height: 880px;
  display: flex;

  &-left {
    width: 80%;

    &-top {
      height: calc(100% - 100px);
      position: relative;
    }

    &-bottom {
      height: 100px;
      max-height: 100px;
      overflow: hidden;
    }
  }

  &-right {
    width: 20%;
  }
}
</style>